package com.googlecode.imanager.client.form;

import com.googlecode.imanager.client.bridge.form.IInputCheck;
import com.googlecode.imanager.client.event.KeyEvent;
import com.googlecode.imanager.client.event.KeyEventType;
import com.googlecode.imanager.client.util.ControlState;
import com.googlecode.imanager.client.util.HasText;
import com.googlecode.imanager.client.util.Utils;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public abstract class InputCheck extends InputControl implements IInputCheck, HasText {

    private static final long serialVersionUID = 1L;

    // TODO avaliar se é melhor usar um label separado ao invés de
    //      ter a propriedade text imbutida no checkbox/radiobutton
    private String text = "";
    private Boolean checked;
    private CheckGroup group;
    
    public InputCheck() {
        super();
    }

    public InputCheck(int width, int height) {
        super(width, height);
    }

    @Override
    protected void handleDefault(KeyEvent e){
        super.handleDefault(e);
        if (!e.isPreventDefault()){
            
            if (e.getEventType() == KeyEventType.KEY_DOWN){
                if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE){
                    clearInput();
                }
            }
            else if (e.getEventType() == KeyEventType.KEY_UP){
                if (e.getKeyCode() == KeyEvent.VK_ENTER
                        || e.getKeyCode() == KeyEvent.VK_SPACE){
                    click();
                }
            }
        }
    }
    
    public Boolean onChanging(Boolean checked){
        return checked;
    }
    
    @Override
    public void clearInput() {
        setChecked(null);
    }

    @Override
    public boolean hasInput() {
        return checked != null;
    }

    public void setChecked(Boolean checked) {
        if (!Utils.isEquals(checked, this.checked)){
            checked = onChanging(checked);
            
            this.checked = checked;            
            getBridge().setChecked(checked);
            
            if (Boolean.TRUE.equals(checked)){
                addState(ControlState.CHECKED);
            } else {
                removeState(ControlState.CHECKED);
            }
            
            onChanged();
        }
    }
    
    public Boolean getChecked() {
        return checked;
    }

    public boolean isChecked() {
        return checked == null ? false : checked;
    }

    public void setGroup(CheckGroup group) {
        if (this.group != group){            
            CheckGroup oldGroup = this.group;
            
            if (oldGroup != null){
                this.group = null;
                getBridge().setGroup(null);
                oldGroup.remove(this);
            }
            
            this.group = group;

            if (group != null){
                group.add(this);
            }
            
            getBridge().setGroup(group);            
        }
    }

    public CheckGroup getGroup() {
        return group;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        if (text == null){
            text = "";
        }
        if (!this.text.equals(text)){
            this.text = text;
            getBridge().setText(text);
        }
    }

    @Override
    public InputCheck clone() {
        InputCheck c = (InputCheck) super.clone();
        
        c.group = null;
        c.setGroup(group);
        
        return c;
    }

    @Override
    protected IInputCheck getBridge() {
        return (IInputCheck) lookupBridge();
    }

}
